package com.cn.fangshuo.util;

import cn.hutool.http.HttpUtil;
import lombok.experimental.UtilityClass;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.MemoryCacheImageOutputStream;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.Iterator;

@UtilityClass
public class ImageUtil {

    /**
     * 从URL获取图片并压缩文件大小(不改变尺寸)，然后转换为Base64
     *
     * @param imageUrl 图片URL
     * @param targetSizeRatio 目标大小比例 (0.1表示压缩到原大小的10%)
     * @return Base64编码的图片字符串
     */
    public String compressImageSizeToBase64(String imageUrl, float targetSizeRatio) throws IOException {

        String formatName = imageUrl.substring(imageUrl.lastIndexOf(".") + 1);

        // 1. 使用Hutool下载图片到字节数组
        byte[] imageBytes = HttpUtil.downloadBytes(imageUrl);

        // 2. 获取原始图片信息
        BufferedImage originalImage = ImageIO.read(new ByteArrayInputStream(imageBytes));
        long originalSize = imageBytes.length;
        long targetSize = (long) (originalSize * targetSizeRatio);

        // 3. 在内存中压缩图片(调整质量而非尺寸)
        byte[] compressedBytes = compressImageByQuality(originalImage, formatName, targetSize);

        // 4. 转换为Base64
        return Base64.getEncoder().encodeToString(compressedBytes);
    }

    /**
     * 通过调整质量压缩图片到目标大小
     */
    private byte[] compressImageByQuality(BufferedImage image, String formatName, long targetSize) throws IOException {

        // 初始化质量参数
        float quality = 0.9f; // 初始质量(0-1之间)
        float minQuality = 0.1f; // 最低质量
        float qualityStep = 0.1f; // 每次调整的步长

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        byte[] compressedData = null;

        // 迭代调整质量直到达到目标大小或达到最低质量
        while (quality >= minQuality) {
            outputStream.reset();

            // 获取JPEG编码器
            Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(formatName);
            if (!writers.hasNext()) {
                throw new IllegalStateException("No writers found for format: " + formatName);
            }

            ImageWriter writer = writers.next();
            ImageWriteParam param = writer.getDefaultWriteParam();

            // 设置压缩模式为显式模式(这样我们可以控制质量)
            param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
            param.setCompressionQuality(quality); // 设置质量

            // 写入压缩后的图片到内存
            try (MemoryCacheImageOutputStream mos = new MemoryCacheImageOutputStream(outputStream)) {
                writer.setOutput(mos);
                writer.write(null, new IIOImage(image, null, null), param);
                writer.dispose();
            }

            // 获取压缩后的数据
            compressedData = outputStream.toByteArray();

            // 检查是否达到目标大小
            if (compressedData.length <= targetSize || quality <= minQuality) {
                break;
            }

            // 未达到目标，降低质量继续尝试
            quality -= qualityStep;
        }
        return compressedData;
    }
}
